package com.wtf.generator.hanlder;


import com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException;
import com.wtf.generator.common.sys.R;
import com.wtf.generator.enums.CommonErrorEnum;
import com.wtf.generator.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.postgresql.util.PSQLException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.io.IOException;
import java.util.Set;

/**
 * date: 2022/6/18 10:59
 * @author linhuanyou
 * @email 496558736@qq.com
 * @version 1.0
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(Exception.class)
    public R handleException(Exception e) {
        log.error("Exception error", e);
       return R.error();
    }

    @ResponseBody
    @ExceptionHandler(RuntimeException.class)
    public R handleRuntimeException(RuntimeException e){
        log.error("RuntimeException error", e);
        return R.error(CommonErrorEnum.OPERATION_ERRO.getErrCode(),CommonErrorEnum.OPERATION_ERRO.getErrMsg());
    }

    @ResponseBody
    @ExceptionHandler(CommonException.class)
    public R handleCommonException(CommonException e){
        log.error("CommonException error", e);
        return R.error(e.getCode(),e.getMsg());
    }

    @ResponseBody
    @ExceptionHandler(IllegalArgumentException.class )
    public R handleIllegalArgumentException (IllegalArgumentException e){
        log.error( "IllegalArgumentException error", e );
        return R.error(CommonErrorEnum.ERROR_VALID.getErrCode(),e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(PSQLException.class)
    public R handlePSQLException(PSQLException e){
        log.error("PSQLException error", e);
        return R.error(CommonErrorEnum.ERROR_DB.getErrCode(),CommonErrorEnum.ERROR_DB.getErrMsg());
    }
    
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class )
    public R handleMethodArgumentNotValidException (MethodArgumentNotValidException e ){
        log.error( "MethodArgumentNotValidException error", e );
        String errorMsg = "";
        for (FieldError error : e.getBindingResult().getFieldErrors()) {
            errorMsg = error.getDefaultMessage();
            break;
        }
        return R.error(CommonErrorEnum.ERROR_VALID.getErrCode(),errorMsg);
    }

    @ExceptionHandler(ConstraintViolationException.class )
    public R handleConstraintViolationException (ConstraintViolationException e ){
        log.error( "ConstraintViolationException error", e );
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        String errorMsg = "";
        for (ConstraintViolation error : constraintViolations) {
            errorMsg = error.getMessageTemplate();
            break;
        }
        return R.error(CommonErrorEnum.ERROR_VALID.getErrCode(),errorMsg);
    }

    @ResponseBody
    @ExceptionHandler(BindException.class )
    public R handleMethodArgumentNotValidException (BindException e ){
        log.error( "MethodBindException error", e );
        String errorMsg = "";
        for (FieldError error : e.getBindingResult().getFieldErrors()) {
            errorMsg = error.getDefaultMessage();
            break;
        }
        return R.error(CommonErrorEnum.ERROR_VALID.getErrCode(),errorMsg);
    }

    @ResponseBody
    @ExceptionHandler(IOException.class )
    public R handleIOException (IOException e){
        log.error( "IOException error", e );
        return R.error(CommonErrorEnum.ERROR_NETWORK.getErrCode(), CommonErrorEnum.ERROR_NETWORK.getErrMsg());
    }
    
    @ResponseBody
    @ExceptionHandler(CannotFindDataSourceException.class )
    public R handleCannotFindDataSourceException (CannotFindDataSourceException e){
        log.error( "CannotFindDataSourceException error", e );
        return R.error(CommonErrorEnum.ERROR_NOT_FIND_DS.getErrCode(),CommonErrorEnum.ERROR_NOT_FIND_DS.getErrMsg());
    }
    
    @ResponseBody
    @ExceptionHandler(NullPointerException.class )
    public R handleNullPointerException (NullPointerException e){
        log.error( "NullPointerException error", e );
        return R.error(CommonErrorEnum.ERROR_NULL.getErrCode(),CommonErrorEnum.ERROR_NULL.getErrMsg());
    }
    
    @ResponseBody
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class )
    public R handleHttpRequestMethodNotSupportedException (HttpRequestMethodNotSupportedException e){
        log.error( "HttpRequestMethodNotSupportedException error", e );
        return R.error(CommonErrorEnum.ERROR_REQUEST_METHOD_NOT_SUPPORTED.getErrCode(),CommonErrorEnum.ERROR_REQUEST_METHOD_NOT_SUPPORTED.getErrMsg());
    }

    @ResponseBody
    @ExceptionHandler(DuplicateKeyException.class )
    public R handleDuplicateKeyException (DuplicateKeyException e){
        log.error( "DuplicateKeyException error", e );
        return R.error(CommonErrorEnum.ERROR_DUPLICATE_KEY.getErrCode(), CommonErrorEnum.ERROR_DUPLICATE_KEY.getErrMsg());
    }
}
